package com.weihao.sd.filter;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.weihao.sd.utils.SHA1;
import com.weihao.sd.utils.TokenThread;
import com.weihao.sd.utils.WxClientUtils;

public class WeixinUrlFilter implements Filter {

	private static Logger logger = LoggerFactory.getLogger(WeixinUrlFilter.class);

	// 这个Token是给微信开发者接入时填的
	// 可以是任意英文字母或数字，长度为3-32字符
	private static String Token = "weixin";

	public void init(FilterConfig config) throws ServletException {
		logger.warn("WeixinUrlFilter启动成功!");
		// 获取web.xml中配置的参数    
        TokenThread.appid = config.getInitParameter("appid");    
        TokenThread.appsecret = config.getInitParameter("appsecret");    
    
        logger.info("weixin api appid:{}", TokenThread.appid);    
        logger.info("weixin api appsecret:{}", TokenThread.appsecret);    
    
        // 未配置appid、appsecret时给出提示    
        if ("".equals(TokenThread.appid) || "".equals(TokenThread.appsecret)) {    
        	logger.error("appid and appsecret configuration error, please check carefully.");    
        } else {    
            // 启动定时获取access_token的线程    
            new Thread(new TokenThread()).start();    
        }    
	}

	public void doFilter(ServletRequest req, ServletResponse res,
			FilterChain chain) throws IOException, ServletException {
		HttpServletRequest request = (HttpServletRequest) req;
		HttpServletResponse response = (HttpServletResponse) res;
		
		// 将请求、响应的编码均设置为UTF-8（防止中文乱码）
		request.setCharacterEncoding("UTF-8");
		response.setCharacterEncoding("UTF-8");
		PrintWriter out = response.getWriter();
		
		// 微信服务器将发送GET请求到填写的URL上,这里需要判定是否为GET请求
		boolean isGet = request.getMethod().toLowerCase().equals("get");
		System.out.println("获得微信请求:" + request.getMethod() + " 方式");
		
		if (isGet) {
			// 验证URL真实性
			// http://localhost:8080/sd/api?echostr=weixin&signature=123343242&timestamp=1232123213&nonce=321
			String signature = request.getParameter("signature");// 微信加密签名
			String timestamp = request.getParameter("timestamp");// 时间戳
			String nonce = request.getParameter("nonce");// 随机数
			String echostr = request.getParameter("echostr");// 随机字符串

			if ("".equals(signature) || "".equals(timestamp)
					|| "".equals(nonce) || "".equals(echostr)) {
				logger.error("参数为空!");
			} else {
				logger.warn(signature + "||" + timestamp + "||" + nonce + "||"
						+ echostr);
				if (checkSignature(timestamp, nonce, signature)) {
					logger.warn("验证通过！");
					out.write(echostr);
				}
			}

		} else {
			// 处理接收消息
			logger.warn("处理接收消息 ");

			// 调用核心业务类接收消息、处理消息
			String respMessage = WxClientUtils.processRequest(request);

			// 响应消息
			out.write(respMessage);
			out.close();
		}
	}

	@Override
	public void destroy() {

	}

	private boolean checkSignature(String timestamp, String nonce,
			String signature) {
		List<String> params = new ArrayList<String>();
		params.add(Token);
		params.add(timestamp);
		params.add(nonce);
		// 1. 将token、timestamp、nonce三个参数进行字典序排序
		Collections.sort(params, new Comparator<String>() {
			@Override
			public int compare(String o1, String o2) {
				return o1.compareTo(o2);
			}
		});
		// 2. 将三个参数字符串拼接成一个字符串进行sha1加密
		String temp = SHA1
				.encode(params.get(0) + params.get(1) + params.get(2));
		if (temp.equals(signature)) {
			return true;
		}
		return false;
	}
}